對我這位初學者而言Concurrency可謂是難阿!,今天看了很多內容但理論居多,最後才想到這個例子跟大家分享JDK7以後Lock、CountDownLatch、CopyOnWriteArrayList的使用,lock的是synchronized的下一版,功能性相同,只是lock延伸其他功能,例如trylock可以指定lock多久,lock底下有一般性的ReentrantLock即用於讀寫的ReentrantReadWriteLock,CountDownLatch是用來提供一個機制讓thread間切換執行,詳細看API吧,常用的方法就是countdown和wait,最後CopyOnWriteArrayList其實就是ArrayList啦,只是支援thread-safe,用法一樣囉,今天自己寫的code如下:
MainTest
package concurrency;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import data.FPR;
public class MainTest {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
final CountDownLatch firstLatch = new CountDownLatch(1); //CountDownLatch是用來管理Thread的類別
final CountDownLatch secondLatch = new CountDownLatch(1); //有一個count參數,及coundown的方法來
//應用排定thread的執行順序
final CopyOnWriteArrayList<FPR> flist=new CopyOnWriteArrayList<>();//這種arraylist是thread-safe的
final FPR f1= new FPR();
final FPR f2= new FPR();
f1.setOriginalNo("Test1"); //測試用的資料1
f2.setOriginalNo("Test2");//測試用的資料2
Lock lock = new ReentrantLock(); //應該可以說取代synchronized的新類別吧.....(
final myCon c1=new myCon("F1", flist, lock);//建立實例並共用同一個lock
final myCon c2=new myCon("F2", flist, lock);//建立實例並共用同一個lock
Thread t1= new Thread(){
public void run(){
flist.add(f1);
c1.trans();
firstLatch.countDown(); //告訴這個thread已經完成了,另外一個Thread可以動作了
try{
secondLatch.await();//要求這個thread暫停
}catch(InterruptedException e){
e.printStackTrace();
}
c1.printInfo();//印出所有資料
}
};
Thread t2= new Thread(){
public void run(){
try {
firstLatch.await();//要求這個Thread等候通知
flist.add(f2);
c2.trans();
secondLatch.countDown();//告訴這個thread已經玩成了,另一個thread可以動作了
} catch (InterruptedException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
c2.printInfo();//印出所有資料
}
};
t1.start();
t2.start();
}
}
myCon
package concurrency;
import java.util.Iterator;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import data.FPR;
public class myCon {
private CopyOnWriteArrayList<FPR> flist;
private Lock lock;
private String name;
private Iterator<FPR> it;
public myCon(String name){
this.name=name;
flist=new CopyOnWriteArrayList<>();
lock= new ReentrantLock();
}
myCon(String name, CopyOnWriteArrayList<FPR> list, Lock lock){
this.name=name;
flist=list;
this.lock=lock;
}
public void add(FPR fpr){
flist.add(fpr);
}
public void trans(){
it=flist.iterator();
}
public void printInfo(){
lock.lock();//取得lock,當使用iterator時,不會被其他執行緒呼叫
try{
if(it!=null){
System.out.print(name+": ");
while(it.hasNext()){
FPR fpr=it.next();
System.out.print(fpr.getOriginalNo()+", ");
}
System.out.println();
}
}finally{
lock.unlock(); //最後要釋放lock,不然其他執行緒無法存取
}
}
}
輸出:
F2: Test1, Test2,
F1: Test1,
在t1執行的時候僅add f1,f2是在t2的時候add,而t1先執行,而t2後執行,故F1僅列出Test1